﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using SPAdvancedSearch.Utility;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace SPAdvancedSearch.Editors
{
    /// <summary>
    /// Defines an editor control for Choice value types.
    /// </summary>
    public class ChoiceEditorControl : EditorControlBase
    {

        #region Fields

        private string _settingsXml = string.Empty;
        private StringCollection _choices;
        private TextBox _choiceOptionsInput;

        #endregion

        #region Ctor

        /// <summary>
        /// Creates an instance of <see cref="ChoiceEditorControl"/>.
        /// </summary>
        /// <param name="managedPropertyName"></param>
        public ChoiceEditorControl(string managedPropertyName)
            : base(managedPropertyName)
        {
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the instructions for the editor.
        /// </summary>
        protected override string EditorInstructions
        {
            get { return "Enter each choice value on a new line."; }
        }

        /// <summary>
        /// Gets the save "type" title.
        /// </summary>
        protected override string SaveTypeTitle
        {
            get { return "Choices"; }
        }

        /// <summary>
        /// Gets the title for the Choice editor.
        /// </summary>
        protected override string EditorTitle
        {
            get { return string.Format("Configure Choices for {0}", this.ManagedPropertyName); }
        }
        /// <summary>
        /// Gets or sets the settings for the editor.
        /// </summary>
        public override string SettingsXml
        {
            get
            {
                //TODO: this is a refactor candidate... requiring each editor control to serialize its own settings does not seem right
                this.EnsureChildControls();
                return SerializationManager.DehydrateObject(this.Choices);
            }
            set
            {
                //TODO: this is a refactor candidate... requiring each editor control to serialize its own settings does not seem right
                this.EnsureChildControls();
                if (!string.IsNullOrEmpty(value))
                {
                    _choices = (StringCollection)SerializationManager.HydrateObjectFromXml(typeof(StringCollection), value);
                }
            }
        }

        /// <summary>
        /// Gets a collection of currently defined choices.
        /// </summary>
        public StringCollection Choices
        {
            get 
            {
                if (_choices == null)
                {
                    _choices = new StringCollection();
                }
                return _choices;
            }
        }

        /// <summary>
        /// Gets the contained <see cref="TextBox"/> for managing choice options.
        /// </summary>
        private TextBox ChoiceOptionsInput
        {
            get
            {
                if (_choiceOptionsInput == null)
                {
                    _choiceOptionsInput = new TextBox();
                    _choiceOptionsInput.TextMode = TextBoxMode.MultiLine;
                    _choiceOptionsInput.Width = Unit.Percentage(95);
                    _choiceOptionsInput.Height = Unit.Pixel(80);
                }
                return _choiceOptionsInput;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Overridden to create the editor for a <see cref="ChoiceValueControl"/>.
        /// </summary>
        protected override void CreateEditor(System.Web.UI.ControlCollection controls)
        {
            this.ChoiceOptionsInput.Load += new EventHandler(ChoiceOptionsInput_Load);
            controls.Add(this.ChoiceOptionsInput);
        }

        /// <summary>
        /// Adds a choice to the list of available choices.
        /// </summary>
        /// <remarks>
        /// This method is used for testing.
        /// </remarks>
        /// <param name="p"></param>
        public void AddChoice(string choice)
        {
            this.Choices.Add(choice);
        }

        /// <summary>
        /// Overridden to save the current editor control's settings.
        /// </summary>
        protected override void SaveSettings()
        {
            string choices = this.ChoiceOptionsInput.Text;
            string[] choiceValues = choices.Split(System.Environment.NewLine.ToCharArray());

            this.Choices.Clear();
            foreach (string choice in choiceValues)
            {
                if (choice.Length > 0)
                {
                    this.Choices.Add(choice);
                }
            }

        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Responds to the event raised when the contained choice options input is loaded.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ChoiceOptionsInput_Load(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.ChoiceOptionsInput.Text))
            {
                // add the choices that are currently defined.
                foreach (string choice in this.Choices)
                {
                    this.ChoiceOptionsInput.Text += choice + System.Environment.NewLine;
                }
            }
        }

        #endregion

    }
}
